package com.apes.fn.server.servicePlan.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.apes.fn.crm.customerExpand.FnCustomerExpand;
import com.apes.fn.server.servicePlan.model.*;
import com.apes.fn.server.servicePlan.repository.QuotationFittingsItemsRepository;
import com.apes.fn.server.servicePlan.repository.QuotationOrderRepository;
import com.apes.fn.server.servicePlan.repository.QuotationWorkItemsRepository;
import com.apes.fn.server.servicePlan.repository.ServicePlanRepository;
import com.apes.framework.api.SpringManager;
import com.apes.framework.jpa.spec.JpaDsl;
import com.apes.framework.plugin.esb.api.SimpleRequest;
import com.apes.framework.util.DateUtil;
import com.apes.framework.util.MapUtil;
import com.apes.scm.masterdata.party.model.PartyRole;
import com.apes.scm.masterdata.product.model.Product;
import com.apes.scm.rbac.model.User;
import com.apes.scm.rbac.repository.PostRepository;
import com.apes.scm.rbac.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @program: apes-server
 * @description:
 * @author: czs
 * @create: 2023-08-02 11:27
 **/
@Service("quotationOrderService")
public class QuotationOrderService extends AbstractPlan {

    @Autowired
    private ServicePlanRepository servicePlanRepository;
    @Autowired
    private QuotationOrderRepository quotationOrderRepository;
    @Autowired
    private QuotationFittingsItemsRepository quotationFittingsItemsRepository;
    @Autowired
    private QuotationWorkItemsRepository quotationWorkItemsRepository;

    public QuotationOrder create(SimpleRequest request){
        QuotationOrder quotationOrder = request.getO(QuotationOrder.class);
        quotationOrder.computeSum();
        if (quotationOrder.getId()!=null){
            quotationOrder = invoke("fn.quotationOrder.update",quotationOrder);
            quotationOrder.setWrite(false);
        }else {
            quotationOrder = quotationOrderRepository.saveAndFlush(quotationOrder);
        }
        return quotationOrder;
    }
    public QuotationOrder update(SimpleRequest request){
        QuotationOrder quotationOrder = request.getO(QuotationOrder.class);
        quotationOrder.computeSum();
        quotationOrder = quotationOrderRepository.saveAndFlush(quotationOrder);
        return quotationOrder;
    }
    public QuotationOrder apply(SimpleRequest request){
        QuotationOrder quotationOrder = request.getO(QuotationOrder.class);
        quotationOrder.setState("apply");
        quotationOrder.setApplyUid(getPerson(request));
        quotationOrder.setApplyDate(new Date());
        quotationOrder = quotationOrderRepository.saveAndFlush(quotationOrder);
        return quotationOrder;
    }
    public QuotationOrder delete(SimpleRequest request){
        QuotationOrder quotationOrder = request.getO(QuotationOrder.class);
        quotationOrder.setState("delete");
        quotationOrder.setDeleteUid(getPerson(request));
        quotationOrder.setDeleteDate(new Date());
        quotationOrder.setApplyUid(null);
        quotationOrder.setApplyDate(null);
        quotationOrder = quotationOrderRepository.saveAndFlush(quotationOrder);
        return quotationOrder;
    }
    public QuotationOrder back(SimpleRequest request){
        QuotationOrder quotationOrder = request.getO(QuotationOrder.class);
        quotationOrder.setState("create");
        quotationOrder.setApplyUid(null);
        quotationOrder.setApplyDate(null);
        quotationOrder = quotationOrderRepository.saveAndFlush(quotationOrder);
        return quotationOrder;
    }
    public Map findOrderCreteQuotation(SimpleRequest request){
        String planId = request.getJO().getString("id");
        List<QuotationOrder> all = quotationOrderRepository.findAll(JpaDsl.toCriteriaIgnoreNull("sourcePlan", "EQ", planId, "state", "in", Arrays.asList("create", "apply")));
        if (!all.isEmpty())return MapUtil.mapped(all.get(0));

        ServicePlan servicePlan = servicePlanRepository.findOne(planId);
        Map map = MapUtil.mapped(servicePlan,"creator","createDate","innerBusinessKey");
        //处理明细
        JSONArray workItems = new JSONArray();
        JSONArray fittingsItems = new JSONArray();
        Double workItemsAmount = 0d;
        Double fittingsItemsAmount = 0d;
        List<ServicePlanItem> servicePlanItems = servicePlan.getServicePlanItems();
        for (ServicePlanItem servicePlanItem : servicePlanItems) {
            String id = servicePlanItem.getProduct().getProductGroup().getId();
            Map planMap = MapUtil.mapped(servicePlanItem);
            Object removeId = planMap.remove("id");
            planMap.put("salesAmount",(Double)planMap.get("saleQty")*(Double)planMap.get("pftPriceUnit"));
            planMap.put("sourceItems",removeId);
            if ("20".equals(id)) {
                fittingsItemsAmount += servicePlanItem.getPftPriceUnit() * servicePlanItem.getSaleQty();
                workItems.add(planMap);
            } else {
                workItemsAmount += servicePlanItem.getPftPriceUnit() * servicePlanItem.getSaleQty();
                fittingsItems.add(planMap);
            }
        }
        map.put("quotationWorkItems",workItems);
        map.put("quotationFittingsItems",fittingsItems);
        FnCustomerExpand fnCustomerExpand = servicePlan.getFnCustomerExpand();
        //报价单主表属性
        map.put("sourcePlan",map.get("id"));
        map.remove("id");
//        map.put("quotationWorkItems",map.get("workItems"));
//        map.put("quotationFittingsItems",map.get("fittingsItems"));
        map.put("customerUnit", fnCustomerExpand.getUnitClientName());
        map.put("workAmountShow",workItemsAmount);
        map.put("partAmountShow",fittingsItemsAmount);
        map.put("salesAmountShow",workItemsAmount+fittingsItemsAmount);
        map.put("salesAmount",workItemsAmount+fittingsItemsAmount);
        map.put("realname",fnCustomerExpand.getRealname());
        map.put("mobile",fnCustomerExpand.getMobile());
        map.put("quotationOrderDate",fnCustomerExpand.getCreateDate());

        map.put("planState",map.get("create"));
        map.put("state","create");
        map.put("belongDeptName",servicePlan.getBelongDept().getName());

        return map;
    }


    public Map findOrderCreteQuotationById(SimpleRequest request){
        String planId = request.getJO().getString("id");

        ServicePlan servicePlan = servicePlanRepository.findOne(planId);
        Map map = MapUtil.mapped(servicePlan,"creator","createDate","innerBusinessKey");
        //处理明细
        JSONArray workItems = new JSONArray();
        JSONArray fittingsItems = new JSONArray();
        Double workItemsAmount = 0d;
        Double fittingsItemsAmount = 0d;
        List<ServicePlanItem> servicePlanItems = servicePlan.getServicePlanItems();
        FnCustomerExpand fnCustomerExpand = servicePlan.getFnCustomerExpand();
        for (ServicePlanItem servicePlanItem : servicePlanItems) {
            String id = servicePlanItem.getProduct().getProductGroup().getId();
            Map planMap = findOldProductOrGetItemMap(servicePlanItem,fnCustomerExpand.getUnitClientName());
            Object removeId = planMap.remove("id");
            planMap.put("salesAmount",(Double)planMap.get("saleQty")*(Double)planMap.get("pftPriceUnit"));
            planMap.put("sourceItems",removeId);
            if ("20".equals(id)) {
                workItemsAmount += (Double)planMap.get("saleQty")*(Double)planMap.get("pftPriceUnit");
                workItems.add(planMap);
            } else {
                fittingsItemsAmount += (Double)planMap.get("saleQty")*(Double)planMap.get("pftPriceUnit");
                fittingsItems.add(planMap);
            }
        }
        map.put("quotationWorkItems",workItems);
        map.put("quotationFittingsItems",fittingsItems);

        //报价单主表属性
        map.put("sourcePlan",map.get("id"));
        map.remove("id");
        map.put("customerUnit", fnCustomerExpand.getUnitClientName());
        map.put("workAmountShow",workItemsAmount);
        map.put("partAmountShow",fittingsItemsAmount);
        map.put("salesAmountShow",workItemsAmount+fittingsItemsAmount);
        map.put("salesAmount",workItemsAmount+fittingsItemsAmount);
        map.put("realname",fnCustomerExpand.getRealname());
        map.put("mobile",fnCustomerExpand.getMobile());
        map.put("quotationOrderDate",DateUtil.format(fnCustomerExpand.getCreateDate(),DateUtil.SHOW_DATE_FORMAT));

        map.put("planState",map.get("create"));
        map.put("state","create");
        map.put("belongDeptName",servicePlan.getBelongDept().getName());

        return map;
    }

    private Map findOldProductOrGetItemMap(ServicePlanItem servicePlanItem,String unitClientName) {
        Product product = servicePlanItem.getProduct();
        Map result = MapUtil.mapped(servicePlanItem);
        if (unitClientName==null||"".equals(unitClientName))return result;
        Sort sort = new Sort(Sort.Direction.DESC, "quotationOrder.createDate");
        if ("20".equals(product.getProductGroup().getId())){
            List<QuotationWorkItems> workItems = quotationWorkItemsRepository.findAll(JpaDsl.toCriteriaIgnoreNull(
                    "quotationOrder.customerUnit", "EQ", unitClientName,
                    "quotationOrder.belongDept", "EQ", servicePlanItem.getServicePlan().getBelongDept(),
                    "product.id", "EQ", product.getId()
            ), sort);
            result = workItems.isEmpty()?result:MapUtil.mapped(workItems.get(0));
        }else {
            List<QuotationFittingsItems> workItems = quotationFittingsItemsRepository.findAll(JpaDsl.toCriteriaIgnoreNull(
                    "quotationOrder.customerUnit", "EQ", unitClientName,
                    "quotationOrder.belongDept", "EQ", servicePlanItem.getServicePlan().getBelongDept(),
                    "product.id", "EQ", product.getId()
            ), sort);
            result = workItems.isEmpty()?result:MapUtil.mapped(workItems.get(0));
        }
        return result;
    }


    public Page<ServicePlan> findAllOrderCreteQuotation(SimpleRequest request){
        List<Map> filters = request.get("condition");
        Sort sort = new Sort(Sort.Direction.DESC, "id");
        PageRequest of = PageRequest.of(request.get("page"), request.get("size"), sort);
        Page<ServicePlan> servicePlans = servicePlanRepository.findAll(JpaDsl.toCriteria(filters), of);
        servicePlans = removeReply(filters, of, servicePlans);
        return servicePlans;
    }

    private Page<ServicePlan> removeReply(List<Map> filters, PageRequest of, Page<ServicePlan> servicePlans) {
        List<ServicePlan> content = servicePlans.getContent();
        int i = 0;
        List<String> ids = new ArrayList<>();
        for (ServicePlan servicePlan : content) {
            List<QuotationOrder> quotationOrders = quotationOrderRepository.findAll(JpaDsl.toCriteriaIgnoreNull(
                    "sourcePlan", "EQ", servicePlan.getId(),
                    "state","NE","delete"
            ));
            if (!quotationOrders.isEmpty()){
                i++;
                ids.add(servicePlan.getId());
            }
        }
        if (i>0){
            filters.add(new JSONObject(mapper("field","id","value",ids,"operator","NIN")));
            servicePlans = servicePlanRepository.findAll(JpaDsl.toCriteria(filters), of);
            servicePlans = removeReply(filters,of,servicePlans);
        }
        return servicePlans;
    }

    public QuotationOrder findOneByPlanId(SimpleRequest request){
        List<Map> filters = request.get("condition");
        List<QuotationOrder> quotationOrders = quotationOrderRepository.findAll(JpaDsl.toCriteria(filters));
        if (quotationOrders.size()==0)return null;
        return quotationOrders.get(0);
    }
    private QuotationOrder changeServerPickCarLog(SimpleRequest request){
        JSONArray ja = request.getJA();
        JSONObject jo = ja.getJSONObject(0);
        String planId = jo.getString("source");
        String mainPlan = jo.getString("mainPlan");
        String pickCarId = jo.getString("id");
        String createDate = jo.getString("createDate");
        String creator = jo.getString("creator");
        QuotationOrder servicePlan = quotationOrderRepository.findOne(planId);
        if (pickCarId.equals(servicePlan.getPickCarId()))return servicePlan;
        servicePlan.setPickCarId(pickCarId);
        servicePlan.setGetCarInfo(creator+" - "+createDate);
        quotationOrderRepository.saveAndFlush(servicePlan);
        PartyRole person = request.getPerson();
        User user = SpringManager.getBean(UserRepository.class).findAll(JpaDsl.toCriteriaByEq("person.id",person.getId())).stream().findFirst().orElse(null);
        if (mainPlan==null)return servicePlan;
        if (!planId.equals(mainPlan))return quotationOrderRepository.findOne(mainPlan);
        return servicePlan;
    }

    private QuotationOrder changeEstimatedDeliveryDate(SimpleRequest request){
        JSONObject jo = request.getJO();
        String planId = jo.getString("id");
        Date estimatedDeliveryDate = jo.getDate("estimatedDeliveryDate");
        if (planId==null)return null;
        if (estimatedDeliveryDate==null)return null;
        estimatedDeliveryDate = DateUtil.dateToDate(estimatedDeliveryDate, DateUtil.SHOW_DATE_FORMAT);
        QuotationOrder servicePlan = quotationOrderRepository.findOne(planId);
        if (servicePlan==null)return null;
        if (servicePlan.getEstimatedDeliveryDate()!=null && estimatedDeliveryDate.getTime() == servicePlan.getEstimatedDeliveryDate().getTime())return servicePlan;
        servicePlan.setEstimatedDeliveryDate(estimatedDeliveryDate);
        quotationOrderRepository.saveAndFlush(servicePlan);
//        PartyRole person = request.getPerson();
//        User user =SpringManager.getBean(UserRepository.class).findAll(JpaDsl.toCriteriaByEq("person.id",person.getId())).stream().findFirst().orElse(null);
        return servicePlan;
    }

    private Map checkQuotationOrderReportDetail(SimpleRequest request){
        JSONObject jo = request.getJO();
        String id = jo.getString("ID");
        QuotationOrder quotationOrder = quotationOrderRepository.findOne(id);
        if (quotationOrder==null)return packageReturnArray(new ArrayList());
        List<Map> arrayList = new ArrayList<>();
        int sort = 0;
        for (QuotationOrderItems servicePlanItem : quotationOrder.getServicePlanItems()) {
            sort++;
            Map mapped = MapUtil.mapped(servicePlanItem);
            mapped.put("sort",sort);

            arrayList.add(mapped);
        }
        Map map = packageReturnArray(arrayList);
        return map;
    }


    /***
     * 包装返回数据
     */
    private Map packageReturnArray(List array) {
        int size = array.size();
        return mapper("serviceplans",array);
//        return MapUtil.mapper(
//                "content", array,
//                "total", size,
//                "size", size
//        );
    }


    private Object searchChangeCondition(SimpleRequest request){
        JSONObject jo = request.getJO();
        JSONArray condition = jo.getJSONArray("condition");
        JSONArray newCondition = new JSONArray();
        for (Object o : condition) {
//            if (o instanceof HashMap)continue;//HashMap格式的一般是权限条件 前端条件是JSON
            if (!(o instanceof JSONObject)){
                newCondition.add(o);
                continue;
            }
            JSONObject jsonObject = (JSONObject) o;
            switch (jsonObject.getString("field")) {
                case "terminal":
                    break;
                default:
                    newCondition.add(jsonObject);
            }
        }
        jo.put("condition",newCondition);
        return jo;
    }
}
